// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2011-2013 Pali Rohár <pali.rohar@gmail.com>
 */

#include <common.h>
#include <command.h>
#include <env.h>
#include <watchdog.h>
#include <malloc.h>
#include <linux/string.h>
#include <linux/fb.h>

#include "loongson_update.h"

extern int panel_count;
extern struct fb_videomode panel[];

/*
* the resolution format is:[x] 800x600
* there have a blank between ] and 800
* the last element of the array must be NULL,
* that determines the end of the array.
*/
char *resolution_menu[64] = {
	NULL
};

static void set_uboot_resolution(char *panel)
{
	char cmd[128] = {0};
	snprintf(cmd, sizeof(cmd), "setenv panel0 %s; setenv panel1 %s; saveenv;", panel, panel);
	printf("set resolution for u-boot.\n");
	printf("%s\n", cmd);
	run_command(cmd, 0);
}

static void set_video_resolution(char *screen_mode)
{
	char cmd[128] = {0};
	snprintf(cmd, sizeof(cmd), "setenv video %s; saveenv;", screen_mode);
	printf("set resolution for video.\n");
	printf("%s\n", cmd);
	run_command(cmd, 0);
}

void update_resolution(char *command, int num)
{
	struct fb_videomode *panelp;
	char var[64] = {0};
	cmd_tbl_t *cmdtp;

	/* Look up command in command table */
	cmdtp = find_cmd(command);
	if ((cmdtp == NULL) && (command[0] != '\0')) {
		panelp = &panel[num];

		set_uboot_resolution((char *)panelp->name);

		snprintf(var, sizeof(var), "VGA-1:%dx%d-32@%d video=VGA-2:%dx%d-32@%d",
			panelp->xres, panelp->yres, panelp->refresh,
			panelp->xres, panelp->yres, panelp->refresh);
		set_video_resolution(var);
	} else {
		run_command(command, 0);
	}
}

void get_resolution(void)
{
	struct fb_videomode *panelp;
	char var[64] = {0};
	int i = 0;

	for (i=0; i<panel_count; i++) {
		panelp = &panel[i];
//		snprintf(var, sizeof(var), "%dx%d@%d=%s|%dx%d-32@%d",
//			panelp->xres, panelp->yres, panelp->refresh,
//			panelp->name,
//			panelp->xres, panelp->yres, panelp->refresh);
		snprintf(var, sizeof(var), "%dx%d@%d=%s",
			panelp->xres, panelp->yres, panelp->refresh,
			panelp->name);
		resolution_menu[i] = strdup(var);
	}

	resolution_menu[i] = NULL;
}

void set_resolution_to_env(void)
{
	char var[64] = {0};
	char *option = NULL;
	int i = 0;

	option = env_get("res_menu_0");
	if (option == NULL) {
		get_resolution();
		while ((option = resolution_menu[i])) {
			snprintf(var, sizeof(var), "res_menu_%d", i);
			env_set(var, option);
			i++;
		}
		env_save();
	}
}

int do_res_menu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	updatemenu_type = UPDATE_TYPE_RESOLUTION;
	updatemenu_return = UPDATEMENU_RETURN_CONSOLE;
	updatemenu_show();

	return 0;
}

U_BOOT_CMD(
	res_menu, 2, 1, do_res_menu,
	"ANSI terminal res_menu",
	"command to select video resolution"
);
